package com.interview.product.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;

import com.interview.core.page.Page;
import com.interview.product.entity.Product;
import com.interview.product.entity.Product_;
import com.interview.product.query.ProductConditionQuery;

@Repository
public class ProductRepository {
	@PersistenceContext
	private EntityManager entityManager;

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public Page findByConditionQuery(ProductConditionQuery producConditionQuery) {
		
		
		Date createDate = producConditionQuery.getCreateDate();
		Date createDateEnd = producConditionQuery.getCreateDateEnd();
		Date expireDate = producConditionQuery.getExpireDate();
		Date expireDateEnd = producConditionQuery.getExpireDateEnd();
		String name = producConditionQuery.getName();
		String code = producConditionQuery.getCode();

		List<Predicate> predicates = new ArrayList<Predicate>();

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

		CriteriaQuery<Product> query = criteriaBuilder
				.createQuery(Product.class);

		Root<Product> root = query.from(Product.class);
		if (name != null) {
			Predicate predicateName = criteriaBuilder.like(
					root.get(Product_.name), "%" + name + "%");
			predicates.add(predicateName);
		}

		if (code != null) {
			Predicate predicateCode = criteriaBuilder.like(
					root.get(Product_.code), "%" + code + "%");
			predicates.add(predicateCode);
		}

		if (createDate != null) {
			Predicate predicateCreateDate = criteriaBuilder
					.greaterThanOrEqualTo(root.get(Product_.createDate),
							createDate);
			predicates.add(predicateCreateDate);
		}
		
		if (expireDate != null) {
			Predicate prediExpireDate = criteriaBuilder.greaterThanOrEqualTo(
					root.get(Product_.expireDate), expireDate);
			predicates.add(prediExpireDate);
		}
		if (createDateEnd != null) {
			Predicate predicateCreatEnd = criteriaBuilder.lessThanOrEqualTo(
					root.get(Product_.createDate), createDateEnd);
			predicates.add(predicateCreatEnd);
		}
		
		if (expireDateEnd != null) {
			Predicate predicatExpireDateEnd = criteriaBuilder.lessThanOrEqualTo(
					root.get(Product_.expireDate), expireDateEnd);
			predicates.add(predicatExpireDateEnd);
		}

		query.where(criteriaBuilder.and(predicates
				.toArray(new Predicate[predicates.size()])));

		TypedQuery<Product> typeQuery = entityManager.createQuery(query);

		Integer pageIndex = producConditionQuery.getPageIndex();
		Integer pageSize = producConditionQuery.getPageSize();
		Integer total = typeQuery.getResultList().size();

		if (pageIndex > 0) {
			pageIndex = pageIndex * pageSize;
		} else {
			pageIndex = 0;
		}

		List<Product> products = typeQuery.setFirstResult(pageIndex)
				.setMaxResults(pageSize).getResultList();

		Page page = new Page();
		page.setPageIndex(pageIndex);
		page.setTotal(total);
		page.setList(products);

		return page;
	}

	public Product findOne(String id) {
		return entityManager.find(Product.class, id);
	}

	public void update(Product product) {
		entityManager.merge(product);
	}

	public void delet(String id) {
		entityManager.remove(findOne(id));
	}

	public Product save(Product product) {
		entityManager.persist(product);
		return product;

	}

	public List<Product> findAll() {

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

		CriteriaQuery<Product> query = criteriaBuilder
				.createQuery(Product.class);

		Root<Product> root = query.from(Product.class);

		TypedQuery<Product> typeQuery = entityManager.createQuery(query);

		List<Product> products = typeQuery.getResultList();

		return products;
	}
}
